<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    JS深拷贝的五种方法
</body>
<script>
    //1、JSON方法实现
    //_tmp和result是相互独立的，没有任何联系，有各自的存储空间。
    let deepClone = function (obj) {
        let _tmp = JSON.stringify(obj);//将对象转换为json字符串形式
        let result = JSON.parse(_tmp);//将转换而来的字符串转换为原生js对象
        return result;
    };

    let obj1 = {
        weiqiujaun: {
            age: 20,
            class: 1502
        },
        liuxiaotian: {
            age: 21,
            class: 1501
        }
    };

    let test = deepClone(obj1);
    console.log(test);
    // JSON对象实现深拷贝的一些问题
    //  *无法实现对对象中方法的深拷贝



    //2、用for…in实现遍历和复制
    function deepClone(obj) {
        let result = typeof obj.splice === "function" ? [] : {};
        if (obj && typeof obj === 'object') {
            for (let key in obj) {
                if (obj[key] && typeof obj[key] === 'object') {
                    result[key] = deepClone(obj[key]);//如果对象的属性值为object的时候，递归调用deepClone,即在吧某个值对象复制一份到新的对象的对应值中。
                } else {
                    result[key] = obj[key];//如果对象的属性值不为object的时候，直接复制参数对象的每一个键值到新的对象对应的键值对中。
                }

            }
            return result;
        }
        return obj;
    }

    let testArray = ["a", "b", "c", "d"];
    let testRes = deepClone(testArray);
    console.log(testRes);
    console.log(typeof testRes[1]);

    let testObj = {
        name: "weiqiujuan",
        sex: "girl",
        age: 22,
        favorite: "play",
        family: { brother: "son", mother: "haha", father: "heihei" }
    };
    let testRes2 = deepClone(testObj);
    testRes2.family.brother = "weibo";
    console.log(testRes2);



    //3. 使用递归的方式实现深拷贝
    //使用递归的方式实现数组、对象的深拷贝
    function deepClone1(obj) {
        //判断拷贝的要进行深拷贝的是数组还是对象，是数组的话进行数组拷贝，对象的话进行对象拷贝
        var objClone = Array.isArray(obj) ? [] : {};
        //进行深拷贝的不能为空，并且是对象或者是
        if (obj && typeof obj === "object") {
            for (key in obj) {
                if (obj.hasOwnProperty(key)) {
                    if (obj[key] && typeof obj[key] === "object") {
                        objClone[key] = deepClone1(obj[key]);
                    } else {
                        objClone[key] = obj[key];
                    }
                }
            }
        }
        return objClone;
    }


    // 4、利用数组的Array.prototype.forEach进copy
    let deepClone = function (obj) {
        let copy = Object.create(Object.getPrototypeOf(obj));
        let propNames = Object.getOwnPropertyNames(obj);
        propNames.forEach(function (items) {
            let item = Object.getOwnPropertyDescriptor(obj, items);
            Object.defineProperty(copy, items, item);

        });
        return copy;
    };
    let testObj1 = {
        name: "weiqiujuan",
        sex: "girl",
        age: 22,
        favorite: "play",
        family: { brother: "wei", mother: "haha", father: "heihei" }
    }
    let testRes2 = deepClone(testObj);
    console.log(testRes2);


</script>

</html>